package com.bifrost.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import com.bifrost.task.support.FtpConnectWrapper;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Author by yanxiaobo
 * Date on 2018/5/28$.
 */
public class FTPUtil {

    public static Logger logger = LoggerFactory.getLogger(FTPUtil.class);

    /**
     * 上传文件。
     *
     * @param files  装有多个文件的集合
     * @param remote 相对路径。指定相对于ftp根目录下的路径。
     * @return
     * @throws IOException
     */
    public static boolean upload(List<File> files, String remote, FtpConnectWrapper ftpConnectWrapper) throws IOException {
        System.out.println("================================logger:" + logger);
        //ftp命令控制端口采用默认的21
        logger.info("开始上传文件");
        boolean result = uploadFile(files, remote, ftpConnectWrapper);
        logger.info("上传文件" + (result == true ? "成功" : "失败"));
        return result;
    }

    public static boolean upload(File file, String remote, FtpConnectWrapper ftpConnectWrapper) throws IOException {
        List<File> files = Lists.newArrayList(file);
        return upload(files, remote, ftpConnectWrapper);
    }

    /**
     * @param files
     * @param remotePath 开放的文件根目录下的文件夹，比如我们开放的根目录是C:\ftpfile，那么C:\ftpfile\img的remotepath = img
     *                   指定的文件路径都是相对于根路径而言
     * @return
     * @throws IOException
     */
    private static boolean uploadFile(List<File> files, String remotePath, FtpConnectWrapper ftpConnectWrapper) throws IOException {
        boolean isUploaded = false;
        FileInputStream in = null;
        FTPClient ftpClient = ftpConnectWrapper.getObject();
        if (!createDir(remotePath, ftpConnectWrapper)) {
            return false;
        }
        try {
            isUploaded = true;
            for (File file : files) {
                logger.info(file.getName());
                in = new FileInputStream(file);
                ftpClient.storeFile(file.getName(), in);//file.getName()ftp服务器下文件名
            }
        } catch (IOException e) {
            logger.error("上传文件出错:", e);
            e.printStackTrace();
            throw e;
        } finally {
            if (null != in) {
                in.close();
                in = null;
            }
        }
        return isUploaded;
    }

    /**
     * 如果指定目录不存在，则创建目录。并将工作目录切换至指定目录下
     *
     * @param dir
     * @return 如果创建路径失败，返回false。否则返回true
     */
    private static boolean createDir(String dir, FtpConnectWrapper ftpConnectWrapper) {
        FTPClient ftpClient = ftpConnectWrapper.getObject();
        if (StringUtils.isBlank(dir)) {
            return true;
        }
        try {
            //校验dir
            if (StringUtils.startsWith(dir, "/")) {
                dir = StringUtils.removeFirst(dir, "/");
            }
            logger.info("当前目录：{}", ftpClient.printWorkingDirectory());
            //切换到基目录
            boolean isRoot = false;
            do {
                if (!ftpClient.changeToParentDirectory()) {
                    isRoot = true;
                }
            }
            while (!isRoot);
            logger.info("当前目录：{}", ftpClient.printWorkingDirectory());
            //尝试切入目录  ,如果切入
            if (ftpClient.changeWorkingDirectory(dir)) {
                logger.info("切换目录成功，当前目录：{}", ftpClient.printWorkingDirectory());
                return true;
            } else {
                logger.info("切换目录{}不成功，尝试创建目录", dir);
                //去除路径最后的/
                dir = StringExtend.trimStart(dir, "/");
                //去除文件路径最开始的/
                dir = StringExtend.trimEnd(dir, "/");
                String[] arr = dir.split("/");
                //循环生成子目录
                for (String s : arr) {
                    logger.info("创建目录：" + s);
                    if (!ftpClient.makeDirectory(s)) {
                        logger.error("创建目录：{}失败", s);
                        throw new RuntimeException("创建目录失败：" + s);
                    } else {
                        logger.info("创建目录{}成功", s);
                        if (!ftpClient.changeWorkingDirectory(s)) {
                            throw new RuntimeException("无法切换到目录：" + s);
                        } else {
                            logger.info("切换目录成功,当前目录{}", ftpClient.printWorkingDirectory());
                        }
                    }
                }
                String workingDirectory = ftpClient.printWorkingDirectory();
                logger.info("创建目录成功,当前目录{}", workingDirectory);
                //将目录切换至指定路径
                return workingDirectory.endsWith(dir);
            }
        } catch (Exception e) {
            logger.error("创建文件夹失败", e);
            throw new RuntimeException(e.getMessage());
        }
    }
}
